{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f6d6452f-a288-449d-adf8-f55d967de2e3",
   "metadata": {},
   "source": [
    "# 实验4 基于分类模型的手写字母识别"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9ecd729-9ab8-4d08-ab89-a95d1a157d7c",
   "metadata": {},
   "source": [
    "## 1.使用torch库载入MNIST数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d8de7b74-373a-4a55-8eff-bc51d7630282",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Image size is (28, 28)\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlEAAAJnCAYAAAC3XwZuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAsdElEQVR4nO3dfXBV5Z3A8V8gECyQbChFYMWkFaq7Hda4ULvrS9EKaHXGMlpro1KsQF/G7bSwK1ssAqIuyk61L07HmaUSVtY6tqW2dYpLbY0IFaxVqFanRiyIMLoqITegRNzc/aND1pQQkoeT3CR8PjN3pjn33Oc+ucmtX55zcm5RPp/PBwAAndKv0BMAAOiNRBQAQAIRBQCQQEQBACQQUQAACUQUAEACEQUAkEBEAQAkEFEAAAlEFNAjLV68OIqKiuKcc84pyPMXFRVFUVFR1NbWFuT5gZ5PRAFHdDBoioqKCj2VPuHga9mR27nnnlvo6QKHUVzoCQAca44//vh27z9w4EDs3r07IiI++tGPdseUgAQiCqCbvfrqq+3e/81vfjP+5V/+JSIiZs6c2R1TAhI4nAfQw3z/+9+PiIizzjorTj755ALPBjgcEQV0mYaGhrjvvvviyiuvjPHjx8ewYcNi0KBBUVFREVdccUVs3Lixw2Pdf//9MWnSpBg2bFgMHjw4JkyYEHfeeWf87//+7xHncMstt8THPvaxKC8vj5KSkhgzZkxUV1d36vm7y29+85t4/vnnIyJi1qxZBZ4N0B4RBXSZO+64I6qrq+Pee++NZ599Ng4cOBARES+//HL84Ac/iDPOOCO+853vHHGcf/3Xf43LL788HnvssYiI2L9/fzz11FPxla98JS666KJoampq83GbNm2Kk08+ORYsWBBPPPFENDY2RklJSbzyyitx3333xRlnnBFLly7t9Pf13hPtt23b1unHt+fgKlRpaWlcdtllmY4NZEtEAV1m5MiRMWfOnNi4cWPU19dHY2NjvP322/HSSy/FV7/61YiImDt3bjz99NOHHWPz5s2xbNmy+Kd/+qd47bXXYvfu3VFfXx833XRTFBUVxX//93/H/PnzD3nctm3b4oILLojXXnstPv3pT8fvfve72L9/f+RyuXjttdfihhtuiP79+8f1118fDzzwQFe9BJ2yd+/euP/++yMi4oorroj3ve99BZ4R0K48wBEsWrQoHxH5rP8v49prr81HRH7mzJntPuf06dPbfPyCBQvyEZEvLi7O79y5s9V9n/70p9t9bD6fz99+++35iMifeuqph9x38LkfeeSRduf2pz/9qd3vsTP+4z/+o2XcJ598MrNxga5hJQoomIsuuigiItavX9/ufgsXLmxz+3XXXRfHHXdcvPvuu/HjH/+4Zfvu3btj9erVERHx9a9//bDjfu5zn4uIiC1btsRrr73W4XkvXrw48vl85PP5qKys7PDjjmT58uUREXHqqafGhAkTMhsX6BoucQB0qZdeeim+973vxSOPPBJbt26NxsbGaG5ubrXPK6+8ctjHjxkzJsaOHdvmfaWlpTFhwoRYv359PPnkky3bH3/88Zbn+MQnPtGheW7fvv2I12/qSn/4wx9i06ZNEeGEcugtRBTQZX7yk59EdXV1qxO/S0tLY9CgQVFUVBTvvPNO1NfXx759+w47xl//9V+3+xwH7/+f//mflm27du1q+d8dXWF66623OrRfVzm4CjVo0KC48sorCzoXoGMczgO6xJtvvhlXX311NDU1xSc+8Ymora2Nt956KxoaGuK1116LV199NX74wx8ecZyUj5o5eNmD4447ruWw25FuhfqMvoiId955J1atWhUREZdeemmUl5cXbC5Ax1mJArrEL37xi8jlclFeXh4///nP2/xLsyNduTui/UN9ERE7d+6MiIgRI0a0bBs5cmRERLz99tvx4osvHvZwYE/x05/+NN54442IcCgPehMrUUCX2LFjR0REnHzyyYf9U/2HH364Q+Ns3bq1zfsaGxvjd7/7XURETJw4sWX7GWec0bKCdd9993Vq3oVw8FDe2LFjY9KkSQWeDdBRIgroEmVlZRER8cILL8T+/fsPuX/z5s1x7733dmism266qc3t3/zmN+Ptt9+O4uLiuOSSS1q2jxgxIj71qU9FRMS///u/xwsvvNDu+Ac/7LcQXn755ZaYvOaaa5IOXwKFIaKATnnjjTfave3ZsyciIqZOnRr9+vWL3bt3x5VXXtly2O2dd96J+++/P6ZOnRpDhw494vOVlZXFypUr46tf/WrLIa/Gxsb4t3/7t5a4uvbaaw85Af2b3/xmvP/9749cLhdnnXVW3H333dHQ0NDq+1i9enVccsklUV1d3anXIMsrlt99993R3NwcxcXFcfXVVx/VWED3ElFAp3zg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AEAhdTqiJk+eHBUVFUfcL5/Px/Lly2PIkCGxcOHCVvfNnz8/ysvL4/vf/37k8/nOTgEAoOC67MTyurq62LVrV5x55pmHHLIbNGhQfPzjH4+dO3fGiy++2FVTAADoMl0aURER48aNa/P+g9sP7teWpqamyOVyrW4AAD1Bl0VUQ0NDRESUlZW1eX9paWmr/dqydOnSKCsra7mNGTMm+4kCACTo0deJmj9/fjQ0NLTcduzYUegpAQBERBd+dt7BFajDrTQdPDR3uJWqiIiSkpIoKSnJfnIAAEepy1aijnTO05HOmQIA6Mm6NKJGjx4dGzZsiH379rW6b//+/bFu3boYPXp0jB07tqumAADQZbosooqKimLWrFmxd+/eWLJkSav7li5dGvX19TFr1qwoKirqqikAAHSZTp8TtXz58li/fn1ERDzzzDMt22prayMiYtq0aTFt2rSIiJg3b1787Gc/i2XLlsXTTz8dEyZMiC1btsSaNWuiqqoq5s2bl813AQDQzTodUevXr4+VK1e22rZhw4bYsGFDRERUVla2RNTgwYOjtrY2brzxxvjRj34UtbW1MXLkyJgzZ04sWrTI5+YBAL1WpyOqpqYmampqOrx/WVlZ3H777XH77bd39qkAAHqsHn2dKACAnqoo34s+ATiXy7V7XSkAjt6ll16a6Xj3339/ZmM9++yzmY117rnnZjbW7t27MxuLnqGhoaHl01UOx0oUAEACEQUAkEBEAQAkEFEAAAlEFABAAhEFAJBARAEAJBBRAAAJRBQAQAIRBQCQQEQBACQQUQAACUQUAEACEQUAkEBEAQAkEFEAAAlEFABAAhEFAJCguNATAODojRgxIrOxvve972U2VkREv37Z/Xt9yZIlmY21e/fuzMbi2GQlCgAggYgCAEggogAAEogoAIAEIgoAIIGIAgBIIKIAABKIKACABCIKACCBiAIASCCiAAASiCgAgAQiCgAggYgCAEggogAAEogoAIAEIgoAIIGIAgBIUFzoCQBw9K699trMxvrABz6Q2VgREfX19ZmN9cc//jGzseBoWYkCAEggogAAEogoAIAEIgoAIIGIAgBIIKIAABKIKACABCIKACCBiAIASCCiAAASiCgAgAQiCgAggYgCAEggogAAEogoAIAEIgoAIIGIAgBIIKIAABIUF3oCAMeqM888M7Oxvv71r2c2Vtam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fRPsw3784x/n161bd8j2devW5QcMGJAfNmxYfv/+/S3bvQey1dnX/1j4/e8Th/N+/etfx9atW+OKK66I0047rWX70KFD44Ybboh33303VqxYUcAZQjYmT54cFRUVR9wvn8/H8uXLY8iQIbFw4cJW982fPz/Ky8vj+9//fuRdJq7TOvozIHuXXHJJnH322YdsP/vss+Pcc8+N3bt3xzPPPBMR3gNdoTOv/7GiT6yn1dbWRkTE1KlTD7nv4LZHH320O6d0zGpqaoqVK1fGzp07o7y8PM4444w49dRTCz2tY05dXV3s2rUrzj///EMOVwwaNCg+/vGPx09/+tN48cUXY9y4cQWa5bHjscceiyeeeCL69+8fp5xySkyePPmYuJpzdxowYEBE/P9hIu+B7vWXr/979eXf/z4RUXV1dRERbb4RysvLY/jw4S370LVeffXVuPrqq1ttu+CCC+Kee+6J4cOHF2ZSx6D23hPv3V5XV+c/IN3gL1dCRo0aFStXrowpU6YUaEZ9y8svvxwPP/xwjBw5MsaPHx8R3gPdqa3X/7368u9/nzic19DQEBF/Pqm5LaWlpS370HWuueaaqK2tjddffz1yuVxs3LgxPvnJT8ZDDz0UF198sWXzbtSR98R796NrVFVVxcqVK2Pbtm3x9ttvR11dXdx0002xZ8+euPjii2PLli2FnmKvd+DAgZg+fXo0NTXFsmXLon///hHhPdBdDvf6Rxwbv/99YiWKnuEv/7XxsY99LB588MGYNGlSrF+/Pn7xi1/ERRddVKDZQfebNm1aq6/Hjh0bCxYsiOOPPz6+8IUvxM033xw//OEPCzO5PqC5uTmuueaaWLduXcyePTumT59e6CkdU470+h8Lv/99YiXq4L80Dvcvilwud9h/jdC1+vXrF5///OcjImLDhg0Fns2xoyPviffuR/eaMWNGFBcXe08chXw+H7Nnz45Vq1bFVVddFXfddVer+70HutaRXv/29KXf/z4RUe89tv2X6uvr44033nDMu4AOngv11ltvFXgmx4723hPv3e59URgDBw6MoUOHek8kam5ujpkzZ8bdd98d1dXVUVNTE/36tf7PmfdA1+nI69+evvT73yciatKkSRERsXbt2kPuO7jt4D50v4NXsv3Li63RdcaNGxejR4+ODRs2xL59+1rdt3///li3bl2MHj06xo4dW6AZHtvq6uqivr7eeyJBc3NzzJo1K1asWBGXX3553HPPPa3OwznIe6BrdPT1b09f+v3vExF13nnnxYc+9KG49957Y/PmzS3bGxsb46abbori4uJD/mKMbD333HOxZ8+eQ7avX78+br/99igpKYlLLrmk+yd2jCoqKopZs2bF3r17Y8mSJa3uW7p0adTX18esWbOiqKioQDPs+xobG+P3v//9Idvr6+tj5syZERFRXV3d3dPq1Q6ugKxYsSIuu+yyWLVq1WH/A+49kL3OvP7Hyu9/Ub6P/MnUI488Eueff36UlJREdXV1lJaWxurVq+NPf/pT3HzzzfGNb3yj0FPs0xYvXhzLli2L8847LyorK6OkpCSeffbZWLt2bfTr1y/uuuuumDVrVqGn2estX7481q9fHxERzzzzTDz11FNx5plntvxretq0aS0nc+7bty/OOuuslo+8mDBhQmzZsiXWrFkTVVVVPvIiUUd/Btu2bYsPfvCDMXHixBg/fnyMGDEidu7cGWvWrIk333wzpkyZEg8++GAMHDiwkN9Or7J48eK48cYbY8iQIfHVr361zWsSTZs2LaqqqiLCeyBrnXn9j5nf/4JdK70LbNq0KX/BBRfky8rK8scdd1x+4sSJ+VWrVhV6WseE2tra/Gc+85n82LFj80OHDs0PGDAgf8IJJ+Q/+9nP5jdt2lTo6fUZM2bMyEfEYW+LFi1qtf+ePXvyc+bMyY8ZMyY/YMCA/JgxY/Jz5szJ79mzpzDfQB/Q0Z9BQ0ND/tprr81PmDAhP3z48HxxcXG+rKwsf9ZZZ+Xvuuuu/LvvvlvYb6QXOtJrH218BI/3QHY68/ofK7//fWYlCgCgO/WJc6IAALqbiAIASCCiAAASiCgAgAQiCgAggYgCAEggogAAEogoAIAEIgoAIIGIAgBIIKIAABKIKACABCIKACDB/wFQvRF3frc1eQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 700x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "from sklearn import svm\n",
    "from sklearn import tree\n",
    "from sklearn.linear_model import LogisticRegression, LinearRegression\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, mean_absolute_error\n",
    "from sklearn.metrics import classification_report, confusion_matrix\n",
    "import seaborn as sns\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.multiclass import OneVsRestClassifier\n",
    "from sklearn.multiclass import OneVsOneClassifier\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "\n",
    "import time\n",
    "\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "color_list = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']\n",
    "\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "label_size = 18 # Label size\n",
    "ticklabel_size = 14 # Tick label size\n",
    "\n",
    "# Load the MNIST dataset to display\n",
    "imgDisp = torchvision.datasets.MNIST(root='./data', train=False, download=True)\n",
    "img, label = imgDisp[0]\n",
    "\n",
    "print(f'Image size is {img.size}')\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(7,7))\n",
    "ax.imshow(img, cmap='gray') # Display image\n",
    "ax.tick_params(axis='both', which='major', labelsize=ticklabel_size) # Set tick label size\n",
    "ax.set_title(f\"Label: {label}\", fontsize=label_size)\n",
    "# plt.savefig(f'exp_character{label}.png', dpi=300) # Make figure clearer\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a441684c-d209-4f05-bbaf-f9d3bb0c44c5",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "## 2.使用transform类对数据进行预处理、提取特征"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dd44307e-b4ab-4ea8-9d28-2540db7d7563",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Class 0: Trainset - 5923 (9.87%), Testset - 980 (9.80%)\n",
      "Class 1: Trainset - 6742 (11.24%), Testset - 1135 (11.35%)\n",
      "Class 2: Trainset - 5958 (9.93%), Testset - 1032 (10.32%)\n",
      "Class 3: Trainset - 6131 (10.22%), Testset - 1010 (10.10%)\n",
      "Class 4: Trainset - 5842 (9.74%), Testset - 982 (9.82%)\n",
      "Class 5: Trainset - 5421 (9.04%), Testset - 892 (8.92%)\n",
      "Class 6: Trainset - 5918 (9.86%), Testset - 958 (9.58%)\n",
      "Class 7: Trainset - 6265 (10.44%), Testset - 1028 (10.28%)\n",
      "Class 8: Trainset - 5851 (9.75%), Testset - 974 (9.74%)\n",
      "Class 9: Trainset - 5949 (9.92%), Testset - 1009 (10.09%)\n",
      "Input_size is 112\n"
     ]
    }
   ],
   "source": [
    "class ftrExtract(object):\n",
    "    '''\n",
    "    This class is used to extract features of images\n",
    "    '''\n",
    "    def __call__(self, tensor):\n",
    "        tensor = tensor.squeeze() # Compress redundant demensions\n",
    "\n",
    "        mean_width = tensor.mean(axis=0)\n",
    "        mean_height = tensor.mean(axis=1)\n",
    "\n",
    "        std_width = tensor.std(axis=0)\n",
    "        std_height = tensor.std(axis=1)\n",
    "\n",
    "        ftrs = torch.cat([mean_width, mean_height, std_width, std_height])\n",
    "\n",
    "        return ftrs\n",
    "\n",
    "# Define a transform to normalize the data\n",
    "transform = transforms.Compose([transforms.ToTensor(), ftrExtract()])\n",
    "\n",
    "# Load the MNIST dataset\n",
    "trainset = torchvision.datasets.MNIST(root='./Data', train=True, download=True, transform=transform)\n",
    "testset = torchvision.datasets.MNIST(root='./Data', train=False, download=True, transform=transform)\n",
    "\n",
    "# Count number of each class in trainset\n",
    "train_class_counts = {}\n",
    "for _, label in trainset:\n",
    "    if label not in train_class_counts:\n",
    "        train_class_counts[label] = 0\n",
    "    train_class_counts[label] += 1\n",
    "\n",
    "# Count number of each class in testset\n",
    "test_class_counts = {}\n",
    "for _, label in testset:\n",
    "    if label not in test_class_counts:\n",
    "        test_class_counts[label] = 0\n",
    "    test_class_counts[label] += 1\n",
    "\n",
    "# Print results\n",
    "for i in range(10):\n",
    "    cls_counts_train = train_class_counts.get(i, 0)\n",
    "    cls_ratio_train = cls_counts_train / len(trainset)\n",
    "    cls_counts_test = test_class_counts.get(i, 0)\n",
    "    cls_ratio_test = cls_counts_test / len(testset)\n",
    "\n",
    "    print(f\"Class {i}: Trainset - {cls_counts_train} ({cls_ratio_train:.2%}), Testset - {cls_counts_test} ({cls_ratio_test:.2%})\")\n",
    "\n",
    "batch_size = 42\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=0)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=0)\n",
    "\n",
    "# Get a batch of training data\n",
    "dataiter = iter(trainloader)\n",
    "data, labels = next(dataiter)\n",
    "\n",
    "input_size = data[0].numpy().shape[0]\n",
    "print(f'Input_size is {input_size}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "557179ba-ce2c-430d-b02b-b64bd35acbb1",
   "metadata": {},
   "source": [
    "## 3.将数据集类型转换为numpy数组，并生成大小数二分类任务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3c4f32c8-affc-417e-8084-4732196453c5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shapes of X_train and Y_train: (60000, 112) and (60000,)\n",
      "Shapes of X_test and y_test: (10000, 112) and (10000,)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Convert data to numpy arrays\n",
    "X_train = []\n",
    "y_train = []\n",
    "for batch_image, batch_label in trainloader:\n",
    "    X_train.append(batch_image.view(-1, input_size).numpy())\n",
    "    y_train.append(batch_label.numpy())\n",
    "\n",
    "X_train = np.vstack(X_train)\n",
    "y_train = np.concatenate(y_train)\n",
    "\n",
    "print(f'Shapes of X_train and Y_train: {X_train.shape} and {y_train.shape}')\n",
    "\n",
    "X_test = []\n",
    "y_test = []\n",
    "for batch_image, batch_label in testloader:\n",
    "    X_test.append(batch_image.view(-1, input_size).numpy())\n",
    "    y_test.append(batch_label.numpy())\n",
    "\n",
    "X_test = np.vstack(X_test)\n",
    "y_test = np.concatenate(y_test)\n",
    "\n",
    "print(f'Shapes of X_test and y_test: {X_test.shape} and {y_test.shape}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7b2bffdd-3cd2-4990-b4a5-36be9eacdac1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted classes: [0 1 2 3 4 5 6 7 8 9]\n",
      "Real classes: [0 1 2 3 4 5 6 7 8 9]\n",
      "Accuracy of linear regression model: 0.2436\n"
     ]
    }
   ],
   "source": [
    "# Initialize the linear regression model\n",
    "lr_model = LinearRegression()\n",
    "\n",
    "# Train the model\n",
    "lr_model.fit(X_train, y_train)\n",
    "\n",
    "# Make predictions on the test set\n",
    "y_pred = lr_model.predict(X_test)\n",
    "\n",
    "# Round predictions to nearest integer for classification\n",
    "y_pred_constrained = np.clip(y_pred, 0, np.max(y_test))\n",
    "y_pred_rounded = np.round(y_pred_constrained).astype(int)\n",
    "print(f\"Predicted classes: {np.unique(y_pred_rounded)}\")\n",
    "\n",
    "# Calculate accuracy\n",
    "accuracy = np.mean(y_pred_rounded == y_test)\n",
    "print(f\"Real classes: {np.unique(y_test)}\")\n",
    "print(f\"Accuracy of linear regression model: {accuracy:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7db8350f-e075-4c4f-a07d-be3ad60bb94d",
   "metadata": {},
   "source": [
    "## 4.使用scikit-learn库构建逻辑回归模型判断大小数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "1ca1aaf5-7459-4a3c-a655-f13e4089b029",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted classes: [0 1 2 3 4 5 6 7 8 9]\n",
      "Accuracy of logistic regression model: 0.8741\n",
      "\n",
      "Classification Report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.92      0.95      0.93       980\n",
      "           1       0.93      0.96      0.95      1135\n",
      "           2       0.86      0.84      0.85      1032\n",
      "           3       0.81      0.84      0.82      1010\n",
      "           4       0.91      0.92      0.91       982\n",
      "           5       0.77      0.69      0.73       892\n",
      "           6       0.92      0.92      0.92       958\n",
      "           7       0.91      0.89      0.90      1028\n",
      "           8       0.83      0.83      0.83       974\n",
      "           9       0.86      0.89      0.87      1009\n",
      "\n",
      "    accuracy                           0.87     10000\n",
      "   macro avg       0.87      0.87      0.87     10000\n",
      "weighted avg       0.87      0.87      0.87     10000\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Initialize the logistic regression model\n",
    "lr_model = LogisticRegression(max_iter=1000)\n",
    "\n",
    "# Train the model\n",
    "lr_model.fit(X_train, y_train)\n",
    "\n",
    "# Make predictions on the test set\n",
    "y_pred = lr_model.predict(X_test)\n",
    "y_pred_proba = lr_model.predict_proba(X_test)\n",
    "\n",
    "# Round predictions to nearest integer for classification\n",
    "y_pred_rounded = np.round(y_pred).astype(int)\n",
    "print(f\"Predicted classes: {np.unique(y_pred_rounded)}\")\n",
    "\n",
    "# Calculate accuracy\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f\"Accuracy of logistic regression model: {accuracy:.4f}\")\n",
    "\n",
    "# Calculate and print classification report\n",
    "print(\"\\nClassification Report:\")\n",
    "print(classification_report(y_test, y_pred))\n",
    "\n",
    "cm = confusion_matrix(y_test, y_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61e9949a-389f-4135-85e0-a2d1fa61ac4b",
   "metadata": {},
   "source": [
    "## 5. 构建Softmax回归模型识别手写字母"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "0a0a4413-1b42-4a02-b110-b6076da39734",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted classes:  [1 2 6]\n",
      "Probabilities:\n",
      "Example 1: 0.05%, 98.27%, 0.03%, 0.20%, 0.31%, 0.06%, 0.26%, 0.01%, 0.76%, 0.04%\n",
      "Example 2: 0.00%, 0.00%, 98.26%, 0.01%, 0.00%, 0.18%, 1.45%, 0.00%, 0.10%, 0.00%\n",
      "Example 3: 0.01%, 0.00%, 0.11%, 0.00%, 0.00%, 0.00%, 99.88%, 0.00%, 0.00%, 0.00%\n"
     ]
    }
   ],
   "source": [
    "# Select three random samples to display the output format, especially the probability distribution before and after Softmax\n",
    "char_1_indices = np.where(y_test == 1)[0]\n",
    "random_char_1_index = np.random.choice(char_1_indices)\n",
    "random_char_1 = X_test[random_char_1_index]\n",
    "\n",
    "char_2_indices = np.where(y_test == 2)[0]\n",
    "random_char_2_index = np.random.choice(char_2_indices)\n",
    "random_char_2 = X_test[random_char_2_index]\n",
    "\n",
    "char_6_indices = np.where(y_test == 6)[0]\n",
    "random_char_6_index = np.random.choice(char_6_indices)\n",
    "random_char_6 = X_test[random_char_6_index]\n",
    "\n",
    "# Get predictions and probabilities for these examples\n",
    "examples = [random_char_1, random_char_2, random_char_6]\n",
    "example_predictions = lr_model.predict(examples)\n",
    "example_probabilities = lr_model.predict_proba(examples)\n",
    "\n",
    "print(\"Predicted classes: \", example_predictions)\n",
    "\n",
    "# Display probabilities in percentage style, one line per example\n",
    "print(\"Probabilities:\")\n",
    "for i, probs in enumerate(example_probabilities):\n",
    "    prob_strings = [f\"{prob:.2%}\" for _, prob in enumerate(probs)]\n",
    "    print(f\"Example {i+1}: {', '.join(prob_strings)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08c366ba-b984-4ce2-b8fd-e755e8cb2f4f",
   "metadata": {},
   "source": [
    "## 6.用混淆矩阵展示逻辑回归的分类结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "5b87eca4-6ef6-45c6-8e1a-3d6db9bbb197",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Real label 0, Predict label 0 (931), Predict label 1 (3), Predict label 2 (2), Predict label 3 (0), Predict label 4 (4), Predict label 5 (6), Predict label 6 (11), Predict label 7 (3), Predict label 8 (18), Predict label 9 (2)\n",
      "Real label 1, Predict label 0 (2), Predict label 1 (1092), Predict label 2 (5), Predict label 3 (3), Predict label 4 (2), Predict label 5 (1), Predict label 6 (5), Predict label 7 (0), Predict label 8 (25), Predict label 9 (0)\n",
      "Real label 2, Predict label 0 (10), Predict label 1 (1), Predict label 2 (865), Predict label 3 (33), Predict label 4 (6), Predict label 5 (65), Predict label 6 (35), Predict label 7 (6), Predict label 8 (10), Predict label 9 (1)\n",
      "Real label 3, Predict label 0 (2), Predict label 1 (14), Predict label 2 (31), Predict label 3 (844), Predict label 4 (0), Predict label 5 (57), Predict label 6 (2), Predict label 7 (28), Predict label 8 (21), Predict label 9 (11)\n",
      "Real label 4, Predict label 0 (6), Predict label 1 (2), Predict label 2 (1), Predict label 3 (1), Predict label 4 (900), Predict label 5 (2), Predict label 6 (7), Predict label 7 (0), Predict label 8 (8), Predict label 9 (55)\n",
      "Real label 5, Predict label 0 (19), Predict label 1 (6), Predict label 2 (47), Predict label 3 (105), Predict label 4 (5), Predict label 5 (618), Predict label 6 (8), Predict label 7 (18), Predict label 8 (57), Predict label 9 (9)\n",
      "Real label 6, Predict label 0 (11), Predict label 1 (7), Predict label 2 (38), Predict label 3 (1), Predict label 4 (11), Predict label 5 (5), Predict label 6 (878), Predict label 7 (0), Predict label 8 (7), Predict label 9 (0)\n",
      "Real label 7, Predict label 0 (4), Predict label 1 (13), Predict label 2 (11), Predict label 3 (9), Predict label 4 (9), Predict label 5 (9), Predict label 6 (0), Predict label 7 (913), Predict label 8 (9), Predict label 9 (51)\n",
      "Real label 8, Predict label 0 (24), Predict label 1 (24), Predict label 2 (1), Predict label 3 (30), Predict label 4 (8), Predict label 5 (35), Predict label 6 (13), Predict label 7 (20), Predict label 8 (806), Predict label 9 (13)\n",
      "Real label 9, Predict label 0 (8), Predict label 1 (7), Predict label 2 (0), Predict label 3 (22), Predict label 4 (47), Predict label 5 (5), Predict label 6 (0), Predict label 7 (19), Predict label 8 (7), Predict label 9 (894)\n"
     ]
    },
    {
     "data": {
      "image/png": "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4OMT0E4cPwoTU1OYmJiiYaPG4hSvYOy/sjtx/CgSE75YfwIe4sDH9cfN3QMWlpZo37ETNqxbA3V1dbi1ao2U1BRs37oZVy5fxMzZc0rUvVvFoY+X7Mvmbty4gR9//BEVK1aEn58f1qxZg61bt6JPn/ydfi+sl81VLKOHX4bUha2FAbQ1VPEqPAF7Lz3HkoP3kZjy+eyJmooSFg90gWsVM5Q11oaGqjLeRSfh/MO3WHzgHh4Hx8jN9/fh9dGnScUc/+aw3y5g29lvf52g2C+b27xxAzZv2oDHAY8QHR0NHR0d2DvUwICBg9GrT19Ra5MCt+ZNcP7c2VzHJ72X3E9X4eLj4zF75nTs27MLkZGRqFKlKiZO8UL3Hj3FLk2yfhjYny+b+ygpKQnz5/pg504/vA0JQRlzc/To2RvTZ86Gunr2J+0pkhiLp1plG7wMCspx3KcXyp0764/Wbs1ybNOwUWMcO6mYe/3EftlcUei/FPmyOQCoXrk8Xr7Mef25H/AMVtbWSE5Oxh+rVmLH9q0IevEcKqqqqFipMoYOG4HuPXsrNESI/bI5Kffx+X3ZnCRDRHx8PKZPn45duzJ3DKpWrQovLy/07Jn/HYPCChHFidghgohKLgl2PZLCxZM3sUNEUaDoEFHUiB0ipCy/IUJylzMBmW/sW758OZYvXy52KURERERE9B+MYUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkiIrYBRS2wLW9oaenJ3YZkmRYe6TYJUha5LVfxC5B0mQymdglUBHG9edrMsQugIgoTzwTQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIw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lDUzgNvgZdnaDehUDxsPXMKDp29Qx946a1xKahr+efy6ML92oev/XR9YWFigpnMtGJuY4OnTJ1ixdAlC373D6rUbxC5PdJ7DhkBXTw+1atdBqVKlEB4ejn17d2PPrp0YN2ESTE2Lx5vLC6qkbH/+X8ePHUVCQgLi4+IAAI8ePcS+vXsAAO6tPaClpSVmeaLh9idvrdxbo3mLlhgzcjjiYmNRoWJF7NrhhxPHj2H9pq2ivyNCkVYsW4J5c2ajpVsrtGrtke2N5nVcXPEyKAgD+/VF1+49UL5CBchkMlw4dw6//boc1Wyro9+AQSJVL47isv5I7mVzAHD0aOZGPS4uDgMHDkS3bt3QvXt3AICHR/426lJ42Zxb8yY4f+5sruOT3ou76L/Vy+YCDvvAytw4x3FVPGbhZUjmNX5O1Swwb0wHuDjYIC0tHWev/4upS/fj+etwuWl2LfkBteysYWygjYjoBJy89Ai+fxzGy5AouXZ5/d2gNxGo2ub/O/Iq9svmFv20EHt270LQi+eIj4+HkZER6tZrgIlTpqJWrdqi1gaIfznD5o0bsHnTBjwOeITo6Gjo6OjA3qEGBgwcjF59+opamxRIffsjFVUqWuNlUFCO4wKePIeVtbViC/pI7K6Z25+vi4+Px+yZ07Fvzy5ERkaiSpWqmDjFC9179BS7NACKe9lc65bNcOF87tuauOQPiIqKguewwbh75w5CQ9/hw4cPsLC0QrsOHTFxshf09fUVUuuXxHzZHCDt9Se/L5uTZIiwtrZGUC4b9efPn8M6Hxt1KYQIqfvWb6wubsQOEVInhU6cqLiSYNcsKdz+fJ2iQkRRJXaIkLL8hghJXs704sULsUsgIiIiIqJcMIYREREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAqYhdQ2NLTM5CeniF2GZIUdf1XsUuQNBvPvWKXIGmPl3cSuwRJU1WWiV2CpCWkfBC7BEnj+pM3NRUeA/0aJRnXISpc/BUSEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRHwjcXFxmO41Ge08WsGqrBm01ZXgO9c7x7a3b99CG/eWMDPShbmZIXp174LngYGKLVgi4uLiMG3qZLRt7QaLMqbQVJVh3hxvscsqVHYW+tgwvC5u/+iBwF864LyPG8a1qQpNVWW5dipKMgxtUQmnZ7VA4C8dEbC0Hf6c3AS1yhvJtQv5o0uOn5GtKivyaxWqu//cQbdObVG9kjVKGWrDytwELRrXx06/rXLtfl/5C5o3qgebcmYw1ddE9UrWGPBdLzx6+ECkysV36eIFdGzfBuZmRjDS04K9bWUs8J0rdlmiuHLpAnp2aYeKFqawMNVFHcdqWPyjb9b4kUMHwlRXNdunbk07EasufHf/uYPundrBrrINShvpwLqsKVo2qY+dftvk2g0fMhAGWirZPrUdq4tUufj4+8rEfSDhisP+j4rYBfzX6dOnsXXrVly6dAmvXr2CgYEBatWqhVmzZsHZ2Vns8nIVGRGBDevWwN6hBtq274CN69fl2O5xQABat2wKhxqO2LxtJ1JSkjHXZzZaNm+Ey9duw9TUVMGViysyIgLr166GvUMNtGvfERvWrxW7pEJVuYwu/pzcFM/exWHWrn8QGZ8K10omGN+mGhwsDTFg1WUAgJIMWD+8LupUNMZvJ/7F9WcR0FJTgYOVAbTUs/9sD918jd9PPpEbFhyZqJDvpAgxMdEoW84CXbv3RBnzskhMSMCuHdsxZGA/vAwKwqSp0wEAkZERaNnKHXb2DjAwNMSL54FYuugnNG9UF2cvXUelylVE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IkEYIoiIiIiISBCGCCIiIiIiEoQhgoiIiIiIBGGIICIiIiIiQRgiiIiIiIhIEIYIIiIiIiIShCGCiIiIiIgEYYggIiIiIiJBGCKIiIiIiEgQhggiIiIiIhKEIYKIiIiIiARhiCAiIiIiIkEYIoiIiIiISBCGCCIiIiIiEoQhgoiIiIiIBGGIICIiIiIiQRgiiIiIiIhIEIYIIiIiIiISREXsAgpbRkYGMjIyxC5DkpSVZGKXIGlcPnl7sqyD2CVIWtlBfmKXIGnB63qJXYKksd/Km6oKj4F+DdehvCWlfhC7BMlKfp+/ZcNfIRERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRICr5aaSkpASZTCZ45jKZDGlpaYKnIyIiIiIi6crXmYhGjRoV6NOwYcPCrr9IuHTxAjq2bwNzMyMY6WnB3rYyFvjOFbss0fmfOY2hgweihl1VGOtro7xVWXTr3AG3bt4UuzTJiIuLw7Spk9G2tRssyphCU1WGeXO8xS5LMkri8qlZ3gi7JzZB0O9dEfRHVxyY2gx1Kpnk2NbByhD7JjdF0B9dEfhbF2wa1QBWpto5tv2hRSVcWdAGb9Z2x61F7TCpox1UlIUfPCoquP3J25BBA6ClppTr59rVK2KXKLr4+HhMHD8WNpbmMNDRgIuzI3bt3CF2WZJx5/ZtdO/SCeWtysJYXxuOdtUwf94cJCYmil2aQl04dxbGOqo5fq5f+/w78hw6MMc2Lk52Ilaft3ydifD39y/kMnK3du1a/PDDD9DW1kZ8fLxodRTUTr/tGDTge3Tp2h1r1m+Cjo4OAgOfIeTNG7FLE93qP1YhMiICniPHoJqtLcLCwrB86WI0buCKQ0eOo0nTZmKXKLrIiAisX7sa9g410K59R2xYv1bskiSlpC0fJxsjHPJqgVvPIzB8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sWPH4O7unuPL5DQ0NDBr1ixcunQJR48ezWFqIiIiIiIqygp0JiI1NRU1a9bMs42zszNSU1MLVBQREREREUlXgUKEs7MzAgIC8mwTEBAAZ2fnAhVFRERERETSVaAQMXfuXPz111+5vgBu/fr1OHLkCObNm/f/1EZERERERBKUr3si5syZk21Y06ZNMWjQIPz000+oX78+zMzMEBoaiosXL+Lx48dwc3PDmTNn0KBBg29eNBERERERiUeWkZGR8bVGSkoFe52ETCbDhw8fCjTt/ys2Nhb6+vp4Gx4NPT09UWqQOplMJnYJRMVW2UF+YpcgacHreoldgqTlo2su0dh/fR3XobwlpYqzf1oUxMbGwsbcGDExMXnuQ+frTMSZM2e+WWFERERERFS05StENG7cuLDrICIiIiKiIqJg1ykREREREVGJVaCXzX3p1atXePPmDVJSUnIc36hRo//3TxARERERkYQUOEQcOnQIkyZNwpMnT/JsJ9aN1UREREREVDgKdDmTv78/OnXqhPj4eIwcORIZGRlo1KgRhgwZAltbW2RkZKBNmzaYNWvWt66XiIiIiIhEVqAQsXDhQujo6ODmzZtYvnw5gMz3RqxatQp3796Fr68vTp06hQ4dOnzTYomIiIiISHwFChHXr19Hx44dUapUqaxh6enpADKf3ezl5QUnJyeeiSAiIiIiKoYKFCISExNRtmzZrH+rq6sjNjZWro2rqysuXrz4/1VHRERERESSU6AQUbp0aYSFhWX9u2zZsnjw4IFcm4iICN5UTURERERUDBUoRNSoUQP379/P+nfTpk1x5swZ7NixAwkJCTh+/Dh27twJBweHb1YoERERERFJQ4FCRPv27XHnzh0EBQUBAKZNmwYdHR306dMHenp68PDwwIcPHzBv3rxvWiwREREREYmvQO+JGDhwIAYOHJj1bxsbG1y/fh1LlixBYGAgrKysMGzYMDg6On6rOomIiIiISCL+7zdWf1KhQgWsXLnyW82OiIiIiIgkqkCXMxERERERUcmVrzMR586dK/AfaNSoUYGnJSIiIiIi6clXiGjSpAlkMlmB/gAf80pEREREVLzkK0TMmjWrwCGCiIiIiIiKF1lGRkaG2EUUhtjYWOjr6yM4NAp6enpilyNJykoMhnlJfp8udgmSlpiSJnYJkmakoyZ2CZLWb9ttsUuQtE19nMQu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RT8txJ7duxD04jni4+NhZGSEuvUaYOKUqahVq7aotQFAv223C2W+qsoydHMsgwY2RjDQUkVUYiouBEZh952QrPc+2JbWgbd75Rynf/A2Dj7HnmT9u5SuOrrWKI1qpXRgoKWKmKT3+DcsAXvuvEVwTHKO8/gWNvUR/wzZWf8zWPzzj7h37y5iY2JQrpwFPNq2xcTJXjA2Nha1tg/pin80Vn76+OTkZPyxaiV2bN+KoBfPoaKqioqVKmPosBHo3rO3QkNEioLepr588U84sHcXgoJeICE+HoaGRnCpWx9jJk5GTWf5bU3w61dwsq2Ibj17Y+VqcQ9maKoqi/a3n/z7L0aOGJJ1ts/CwhJdu/fAhElTJXG2KjY2FmVMDRATE5PnPrSgEOHj44OZM2d+syJzsnDhQuzcuRPPn3/u+Bo0aAAvLy/Urp3/jk+MEFHUSCFESJnYIULqCjNEFAdihwipK6wQUVxIIURImRghoqhRVIgoqsQMEVJXKCHCwMAABgYG+S5CJpPh2TNxnkTAEPF1DBF5Y4jIG0NE3hgi8sYQkTeGiLwxRHwdQ0TeGCJyl98QIeieiOjoaESXsMeQEhERERGRPEHPNvT29kZ6erqgDxERERERFS8l6wHpRERERET0f2OIICIiIiIiQRgiiIiIiIhIEIYIIiIiIiISJN9PZ+JN0kREREREBPBMBBERERERCcQQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIKoiF1AYVOSyaAkk4ldBhVBSlxt8mSsqy52CZKWnp4hdgmStqmPk9glSJr18D1ilyBpQb93E7sEyVNmJ5YnGfcNc6WUz3WHZyKIiIiIiEgQhggiIiIiIhKEIYKIiIiIiARhiCAiIiIiIkEYIoiIiIiISBCGCCIiIiIiEoQhgoiIiIiIBGGIICIiIiIiQRgiiIiIiIhIEIYIIiIiIiIShCGCiIiIiIgEYYggIiIiIiJBGCKIiIiIiEgQhggiIiIiIhKEIYKIiIiIiARhiCAiIiIiIkEYIoiIiIiISBCGCCIiIiIiEoQhgoiIiIiIBGGIICIiIiIiQRgiiIiIiIhIEIYIIiIiIiIShCGCiIiIiIgEYYggIiIiIiJBGCKIiIiIiEgQhggiIiIiIhKEIYKIiIiIiARhiCAiIiIiIkEYIr6RuLg4TPeajHYerWBV1gza6krwneudrd2lixcwYthg1HetBUNdDWirKyHoxQuF1ysFQwYNgJaaUq6fa1eviF2iwtz95w66d2oHu8o2KG2kA+uypmjZpD52+m2Ta5eRkYFN69eicb06sChlCJtyZvBwa4rjRw+LVLm44uLiMG3qZLRt7QaLMqbQVJVh3hxvsctSOG5/hDt31r/EbnvsLAyw0bMe/lnUFs9XdsKFua0wvm01aKopZ7V5t7Zbrp8Lc1vJzc9UTx3zezvh2oLWePFbZ9z40QNL+9VCWSNNRX81hYqPj8fE8WNhY2kOAx0NuDg7YtfOHWKXJRns4/NWHNYfFbELyM2FCxcwf/58XL58GcnJyShXrhy+//57zJw5U+zSchQZEYEN69bA3qEG2rbvgI3r1+XYzv/MKZw5fQo1ajhBT08P5876K7ZQCZk6bQYGDxmabXjXTu2hpq4O51q1RahKHDEx0ShbzgJduvdEGXNzJCYkYPdOPwwd1A8vg15g0tTpAID5c73x80JfDBw8FN5zfZGcnIzVv69Ejy4dsHn7brTv2Enkb6JYkRERWL92NewdaqBd+47YsH6t2CWJgtufgvOZ64vGTZrKDbOtbidSNYWvchld/OXVDM/exmHmjjuIjE+Ba2VTTGhnixpWhui38hIAwGP+qWzT1rQxwrxeTjh6OzhrmJqKEg5Obgp9bTX8fPAB/g2JRYVSupjcoTqaVC+FBjOPIyElTWHfT5F6duuMmzeuY67vQlSqXBk7/bajX99eSE9PR89evcUuT3Ts4/NWHNYfSYaI7du347vvvkP37t2xefNm6Ojo4NmzZ3jz5o3YpeXK0soKwe8iIZPJEB4enmsnPnXaTEybMRsAsGzJohLdiZevUAHlK1SQG3b+3FmEh4djitd0KCsr5zJl8dOwURM0bNREbpi7R1sEvXiOTevXZoWIbZs3om69+liyYmVWu6bNW6KyTVn4bdtc4kKEpZUVQsKisn53JTVEcPtTcBUrVkIdF1exy1CYzi6W0FRTxsBVlxAUlgAAuBAQhlL6Gvi+cQXoa6kiJvE9bgZGZpv2u8blkZ6egW0XnmcNc61kggqldTFu43Vsv/ACAHDpcRjik9/j9yGuaGRrhqO3pdt3F9Sxo0dw6u+T2LhlO3r07AUAaNykKV6+DMK0qZPQrXuPEtWH5YR9fO6Ky/ojuRARHByMIUOGYOjQofjtt9+yhjdt2jSPqcQnk8ny1U5JiVeQ5WXThvWQyWTo13+g2KVIgrGxCcLCwrL+raKqCj09fbk2Ghoa0FDXgIaGhqLLE11+f3fFHbc/lF/vP2QAAOKS3ssNj0l8jw/pGXiflp7jdNrqKmjvbIHL/4bhRWjCF/PLbB+bw/wAIOV9zvMr6v48sB86Ojro0rWb3PDv+g1A/+9649rVq6hbr55I1UkX+/hMxWX9kVyPsnbtWiQkJGDKlClil0IKFhMTg/379qBps+awtrERuxxRpKenIy0tDeFhYVj7xyqc+vsExo6flDV+mOco/H3yODZvXI/oqCi8DQnBtCkTEBsbg6EjRopYOVHRNG7MSOhqqqKUsT7at3HHpYsXxC6pUO269ALRCan4sW9NWJloQ1tdBS0dyuD7xuWx4cxTJKZ+yHG6TnUsoK2hgm3nn8sNv/Y0AndeRGJS++pwtDaElroy7C0NMK2zHf4JisK5R+8U8bUU7sGD+6hStRpUVOSPxdrbOwAAHj64L0ZZksY+/rPisv5I7kzEuXPnYGRkhICAAHTo0AH379+HkZEROnfujJ9++gl6enpil0iFZNdOPyQlJZXoIxQTxozEhnWrAQBqamr4cdEyDBg8JGv8iJFjoKmhiUnjRmH0iMzhhkZG2LHnAFzr1helZqKiSE9PH56jRqNhoyYwNjbGs2dPsWzxIrRq0RT7Dv6Flm6tvj6TIuhVRCLaLDiNDZ71cG2hR9bwNX8/wYwdd3KdrncDG0QnpOKvm6/lhn9Iz0Dnn89i1Q8uOD6jRdbwiwGhGLjqEtI+nvkobiIjI2BjUz7bcEMjo6zxJI99/GfFZf2RXIgIDg5GYmIiunXrBi8vLyxbtgzXr1/H7Nmzcf/+fZw/fz7HU/cpKSlISUnJ+ndsbKwiy6ZvYNOG9TA2Ni5x1/V/afzkqfi+/0CEhYXi2JHDmDR+NBITEzBq7AQAwNbNGzF10jj8MGwEWrq5IzU1FTu2b0Xv7p2xxW83mrcsnjs+RN+ao5MTHJ2csv5dv0FDtO/QCbVrOmCG15RiGyIsjLWwZVR9hMWmYOBvlxARl4Ka5Y0wro0ttNVVMG7TjWzTVDHXg3MFY6w7/RQp/7ncSUVZhtXDXFHVXB/jN93A07dxsDTRxrg21bBrfGN0WeSPuKTieWN1npcR8lLLbNjHyysO64/kQkR6ejqSk5Mxe/ZsTJ06FQDQpEkTqKmpYezYsTh16hRatGiRbboFCxbAx8dH0eXSN3Lv7l3cunkDnqNGQ11dXexyRGNhYQkLC0sAgJt75lFCn1nT0avP91BRUcGkcaPwff9BmLfg56xpWrZqjTatmmHcaE/cffRUlLqJigMDAwO09miDtav/QFJSEjQ1i98jSmd0sYeupiqa+5zMunTpypNwRManYvmA2th1+QUu/xsuN03vBpmXnmw7H5htfr0b2KCFfRm4zf0b/wRFAQCuPgnHtSfhuLbQA0NaVMbiQw8L+VspnpGRMSIish8tjorMvCHdyNBI0SVJGvt4ecVl/ZHcPRHGxsYAgFat5I8CtW7dGgBw69atHKfz8vJCTExM1ufVq1eFWyh9U5s2Zj5Npv+AwSJXIi01a9VGWloaXjwPxJMnj5GUlAQn51rZ2jnVdMbLoBeIj48XoUqi4iMjI/Pym+J60351CwP8+yY2270Pd55n7rxULSv/4AZVZRm61rXCnReRePAqJtv87CwMkPYhHXdfRskNDwpPQERcCqqWLZ6XINvZ2eNxwCOkpcmfZbl//x6A4v2Y4IJgHy+vuKw/kgsRDg4OOQ7/tGHP7eki6urq0NPTk/tQ0ZCSkoId27ehVu06qG5XNH44inL+nD+UlJRgbVMepcuYAwBuXLsq1yYjIwM3rl2FgaEhtLW1xSiTqFiIiorC0SOH4VDDsdg+7exddDKqmOtBS13+8ZG1KmQewAuJSpIb3srRHCa66th+Qf6G6k/eRidBRVkJTtbyR07Ll9KBsa56tvkVF+07dkJ8fDz279srN3zblk0oY26OOi4uIlUmPezjsysu64/kLmfq0qULVq9ejaNHj8Lpi+tVjxw5AgBwdZXu87yPHzuKxMQExMXFAQACHj3C/n17AACt3D2gpaWFsLAwXDh/FkDm3fkAcOL4UZiYmsLExBQNGzUWp3gRHTp4AJGRkZjjO0jsUkQzxnMYdPV04VyrDkzNzBAREYGD+/Zg355dGD1uAkxMTQEA7Tp0wsb1a6Cmrg63Vu5ISUmB37YtuHL5EqbP8im2R0/zcvzYUSQkJCD+4+/u0aOH2Lc383fn3jrzd1cScPsjTP/v+sDCwgI1nWvB2MQET58+wYqlSxD67h1Wr90gdnmFZvXf/2KjZ33sHt8Yf5z8F5HxKXAub4zRHlUREByDU/dC5Nr3bmCDxJQ07Lv6Msf57bj4AkNbVsa64XWx9PAjPHsbBytTbYzxqIaE5DRs8n+miK+lcK3cW6N5i5YYM3I44mJjUaFiReza4YcTx49h/aatReIZ/4rCPj674rL+yDI+HeKXkPbt2+PEiROYMWMGXF1dcePGDfj4+KBFixY4dOhQvuYRGxsLfX19hIRFK+ysRLXKNngZFJTjuIePA2FlbY1zZ/3R2q1Zjm0aNmqMYyfPFGaJcqSyv9nOoxWuXL6EwJdvoKurK3Y5WVJzeV56Ydi6eSO2bdmIfx8HICY6Gto6OrCzd8D3/QehR68+We2Sk5Ox5veV2OG3DS9fPIeKqioqVqyEH4Z5oluPXgoNEeqq0tjIValonevvLuDJc1hZWyu2oI/S0xW7aeX2R5hFPy3Ent27EPTiOeLj42FkZIS69Rpg4pSpqCWBN+laD99TaPOuX8UUo1pXhW05fehqquJNVBJO/PMGK44EICohNauduaEmbvzYBnuuBGH0+uu512qmjQltbeFayRRmBhoIi03GzWcRWHzoIf4NiSuU7xD0e7evNypk8fHxmD1zOvbt2YXIyEhUqVIVE6d4oXuPnmKXBuDzFRxik2ofL/ZBNymvP7GxsShlrI+YmJg896ElGSKSkpLg4+OD7du3IyQkBObm5ujTpw9mz56d7xtyxAgRRY3YnbjUKTJEFEVSCRFSpegQUdRw+5O3wgwRxYEUQoTUSXD3TlLEDhFSlt8QIbnLmQBAU1MTCxcuxMKFC8UuhYiIiIiI/kNyN1YTEREREZG0MUQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAqYhdQ2JSUZFBSkoldhiR9SM8QuwRJU1Vmxs5LOtcf+j9kcPXJU9Dv3cQuQdJK99sqdgmS92ZDH7FLkLTk9x/ELkGyklLzt2y4l0RERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDBBERERERCcIQQUREREREgjBEEBERERGRIAwRREREREQkCEMEEREREREJwhBBRERERESCMEQQEREREZEgDBFERERERCQIQwQREREREQnCEEFERERERIIwRBARERERkSAMEUREREREJAhDhIJtWLcWmqoymBjoiF2KQsXFxWGG12S092gFq7Jm0FFXgu9c72ztfvt1BZo2rAtLc1MY6WqgakUr9OvbCw8fPlB80QoUFxeH6V6T0e7j8tHOZflcungBI4YNRn3XWjDU1YC2uhKCXrxQeL1SceP6NbRv445SxnowM9JFa7dmuHzpothlSQaXT964fPIWHx+PiePHwsbSHAY6GnBxdsSunTvELqvQ1SxvjL1TmuHV2h54va4HDk1vAZfKptnauVY2xYrBrvCf1xrvNvZC9La+sDTRztZOS10Z60Y2wPWf2+PV2h4IXtcTl39si4kd7aClrqyIryQK/r4yXTjnDyNtlRw/169dyWp35dIFjB4xBE3r10FpQy0YaavgZdAL8QrPB4YIBQoODobXlIkoY24udikKFxkRgQ3r1iAlNQXt2nfIvV1kBFq2csfKVWtw8PBxTJ/pjbt3bqNpA1f8+/ixAitWrE/LJzU1BW3zWD7+Z07hzOlTsLCwhGvdegqsUHpu3rgOt+aNkZychLXrN2Pths1ITk5GG/cWuHrlstjliY7LJ29cPl/Xs1tnbNuyCdNnzMbBv47CuVZt9OvbCzv8totdWqFxKm+MIzPdoKmmjGGrLmLYqktQV1XGQa8WqF3RRK5tY7vSaGJXGq/DE3DtSViu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3l36PR5ERERERPSe2l4TceTIEakjEBERERFRPtT2SAQREREREaknFhFERERERCQKiwgiIiIiIhKFRQQREREREYnCIoKIiIiIiERhEUFERERERKKwiCAiIiIiIlFYRBARERERkSgsIoiIiIiISBQWEUREREREJAqLCCIiIiIiEoVFBBERERERicIigoiIiIiIRGERQUREREREorCIICIiIiIiUVhEEBERERGRKCwiiIiIiIhIFBYRREREREQkCosIIiIiIiIShUUEERERERGJwiKCiIiIiIhEYRFBRERERESisIggIiIiIiJRWEQQEREREZEoLCKIiIiIiEgUFhFERERERCQKiwgiIiIiIhKFRQQREREREYnCIoKIiIiIiETRkjpAUcvKzkFWdo7UMagY0tRkjV2QzCz+rgqirSmTOoJa4/enYFrcx1egZ6t7Sh1B7dWYckjqCGotbE4bqSOoLR2twi1/uJQiIiIiIiJRWEQQEREREZEoLCKIiIiIiEgUFhFERERERCQKiwgiIiIiIhKFRQQREREREYnCIoKIiIiIiERhEUFERERERKKwiCAiIiIiIlFYRBARERERkSgsIoiIiIiISBQWEUREREREJAqLCCIiIiIiEoVFBBERERERicIigoiIiIiIRGERQUREREREorCIICIiIiIiUVhEEBERERGRKCwiiIiIiIhIFBYRREREREQkCosIIiIiIiIShUUEERERERGJwiKCiIiIiIhEYRFBRERERESisIggIiIiIiJRWEQQEREREZEoLCKIiIiIiEgUFhH/kdCQ4xg6qD9qV3eDjbkRKlW0R7cvOuHqlcsfnEcQBPi28IaRnibGBI1UYVrV4/h8mqSkJEyeOB7t27aGfTkr6GvLMHvWDKljqdz1a2Ho4t8e1VydYGNmAEdbS7T0aoKtWzYq9Q27egUd2rWGraUxHMqa48tunfHo0UMJUksv7OpVdO3sj4qOdrAwMUBN96qYO3sWUlNTpY6mUtevhaGrvx/cK1VAWXNDONlZoZV3E2zdskmh39BB/WBaRkvpVa9mNYmSq05SUhKCJ41Hh3a+cLSzhqGuBuZ8M0Op3/Ifl8GnWSM42FrB3EgPVVwcEdCrB27ejFB9aBURs/4Ku3oFfm1bo6yFMcrbmKNnt8549LBkLX/cbI2xPKA2Tgf74Pqc1jg0rhlGtHSBnrbi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22Ps+EmweHcOt1RU+/1Zi00b1uLundvy74+7R3V81ac/uvX4EgAQHxeHEUMH4vq1MES9eY3s7GzYOziifYeO+HrcJKU7BhY1KZY/bpUqfHBZE3HnIcqWK4cxQSNw7uxZPH/2FOnp6bApWxbNPL0xZvxEVK3qlu+8RUGVmy5i1l9Xr1zGtCmTcDFv+ePtgznzFik88FFViuJhcwDQwNkcg30qonI5IxjpaeNlfBqO33qDFccfyq9xAIBqdsYY91ll1HI0RXa2gHMPYrBg3x2Fh9Tl6VK/PAKaOqGClQGSM7Jw6k4UFh+4i1cJRXdbXFU+bA4oXr+vwj5sTu2KiD179qBTp05o0KABRo8eDUtLS5w/fx7z5s2Dg4MDrl69WqjbvKq6iKCSR12KCHWlDk8cVmfqUESoM35/CsblT8HUbNNFLRVVEVFSqLqIKE6K7ROrO3TogGPHjsHY2BiBgYFo37491q1bh8GDB+PkyZPF6jkRREREREQlkdpdEwEAPj4+8PHxkToGERERERHlQ+2ORBARERERkXpjEUFERERERKKwiCAiIiIiIlFYRBARERERkSgsIoiIiIiISBQWEUREREREJAqLCCIiIiIiEoVFBBERERERicIigoiIiIiIRGERQUREREREorCIICIiIiIiUVhEEBERERGRKCwiiIiIiIhIFBYRREREREQkCosIIiIiIiIShUUEERERERGJwiKCiIiIiIhEYRFBRERERESisIggIiIiIiJRWEQQEREREZEoLCKIiIiIiEgUFhFERERERCQKiwgiIiIiIhKFRQQREREREYnCIoKIiIiIiERhEUFERERERKKwiCAiIiIiIlFYRBARERERkSgsIoiIiIiISBQtqQMUNU0NGTQ1ZFLHICpx+LMqWPrbHKkjqDU9be7DKohMxh9YQbKyBakjqL3rc9tIHUGt2Q/cKnUEtZWTmVqoflyKExERERGRKCwiiIiIiIhIFBYRREREREQkCosIIiIiIiIShUUEERERERGJwiKCiIiIiIhEYRFBRERERESisIggIiIiIiJRWEQQEREREZEoLCKIiIiIiEgUFhFERERERCQKiwgiIiIiIhKFRQQREREREYnCIoKIiIiIiERhEUFERERERKKwiCAiIiIiIlFYRBARERERkSgsIoiIiIiISBQWEUREREREJAqLCCIiIiIiEoVF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",
      "text/plain": [
       "<Figure size 1000x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def manual_confusion_matrix(y_true, y_pred, num_classes):\n",
    "    cm = np.zeros((num_classes, num_classes), dtype=int)\n",
    "    for t, p in zip(y_true, y_pred):\n",
    "        cm[t][p] += 1\n",
    "    return cm\n",
    "\n",
    "# Get number of character types\n",
    "num_classes = len(np.unique(y_test)) \n",
    "\n",
    "# Calculate confusion matrix\n",
    "cm = manual_confusion_matrix(y_test, y_pred_rounded, num_classes)\n",
    "\n",
    "# Print the results in the specified format\n",
    "for i in range(num_classes):\n",
    "    output = f\"Real label {i}, \"\n",
    "    for j in range(num_classes):\n",
    "        output += f\"Predict label {j} ({cm[i, j]}), \"\n",
    "    print(output[:-2])  # Remove the last comma and space\n",
    "\n",
    "# Now let's create the confusion matrix plot\n",
    "fig, ax = plt.subplots(figsize=(10, 8))\n",
    "\n",
    "# Plot the confusion matrix as a heatmap\n",
    "im = ax.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)\n",
    "\n",
    "# Set up the axes\n",
    "ax.set(xticks=np.arange(cm.shape[1]),\n",
    "       yticks=np.arange(cm.shape[0]),\n",
    "       xticklabels=np.arange(10), yticklabels=np.arange(10),\n",
    "       xlabel='Predicted label', ylabel='True label')\n",
    "\n",
    "# Loop over data dimensions and create text annotations\n",
    "for i in range(cm.shape[0]):\n",
    "    for j in range(cm.shape[1]):\n",
    "        ax.text(j, i, format(cm[i, j], 'd'),\n",
    "                ha=\"center\", va=\"center\", fontsize=12,\n",
    "                color=\"white\" if cm[i, j] > cm.max() / 2. else \"black\")\n",
    "\n",
    "# Adjust font sizes\n",
    "ax.set_xlabel('Predicted label', fontsize=14)\n",
    "ax.set_ylabel('True label', fontsize=14)\n",
    "\n",
    "ax.tick_params(axis='both', which='major', labelsize=12)\n",
    "\n",
    "# Tight layout to ensure everything fits\n",
    "fig.tight_layout()\n",
    "\n",
    "# Save the figure if needed\n",
    "# plt.savefig('Logicregression_for_classification.png', dpi=300, bbox_inches='tight')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "459827f9-8209-422e-a7a5-b56d50fc0e32",
   "metadata": {},
   "source": [
    "## 7.构建支持向量机判断大小数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "adf73c36-48e0-49b0-81d8-092c8952df03",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training time: 88.98 seconds\n",
      "Precision: 0.9755, Recall: 0.9454, Accuracy: 0.9911, F1-Score: 0.9602\n"
     ]
    }
   ],
   "source": [
    "# Extract features and labels from trainset\n",
    "x_train = []\n",
    "y_train = []\n",
    "for image, label in trainset:\n",
    "    x_train.append(image.numpy())\n",
    "    y_train.append(1 if label == 1 else 0)  # Set label to 1 for character 1, 0 otherwise\n",
    "\n",
    "x_train = np.array(x_train)\n",
    "y_train = np.array(y_train)\n",
    "\n",
    "# Extract features and labels from trainset\n",
    "x_test = []\n",
    "y_test = []\n",
    "for image, label in testset:\n",
    "    x_test.append(image.numpy())\n",
    "    y_test.append(1 if label == 1 else 0)  # Set label to 1 for character 1, 0 otherwise\n",
    "\n",
    "x_test = np.array(x_test)\n",
    "y_test = np.array(y_test)\n",
    "# Define SVM classifier\n",
    "mdl_svm = svm.SVC(kernel='linear', probability=True)\n",
    "\n",
    "# Train model\n",
    "start_time = time.time()\n",
    "mdl_svm.fit(x_train, y_train)\n",
    "end_time = time.time()\n",
    "\n",
    "print(f'Training time: {end_time - start_time:.2f} seconds')\n",
    "# Make predictions and evaluate the model\n",
    "y_pred_svm = mdl_svm.predict(x_test)\n",
    "y_proba_svm = mdl_svm.predict_proba(x_test) # Output ratio\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred_svm)\n",
    "precision = precision_score(y_test, y_pred_svm)\n",
    "recall = recall_score(y_test, y_pred_svm)\n",
    "f1 = f1_score(y_test, y_pred_svm)\n",
    "\n",
    "print(f'Precision: {precision:.4f}, Recall: {recall:.4f}, Accuracy: {accuracy:.4f}, F1-Score: {f1:.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ca9af82-6d65-4f44-9939-6c5b22cf1803",
   "metadata": {},
   "source": [
    "## 8.构建基于支持向量机的一对多模型识别手写字母"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "cd444d34-9fac-4390-b61b-4b147da6ba3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training time: 0.23 seconds\n",
      "Accuracy: 0.9896\n"
     ]
    }
   ],
   "source": [
    "# Define logic multi-classifier\n",
    "mdl_logic_ovr = OneVsRestClassifier(LogisticRegression(max_iter=1000))\n",
    "\n",
    "# Train model\n",
    "start_time = time.time()\n",
    "mdl_logic_ovr.fit(x_train, y_train)\n",
    "end_time = time.time()\n",
    "\n",
    "print(f'Training time: {end_time - start_time:.2f} seconds')\n",
    "\n",
    "# Make predictions and evaluate the model\n",
    "y_pred_logic_ovr = mdl_logic_ovr.predict(x_test)\n",
    "y_proba_logic_ovr = mdl_logic_ovr.predict_proba(x_test) # Output ratio\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred_logic_ovr)\n",
    "print(f'Accuracy: {accuracy:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "01488820-6b97-4e2d-878e-7aadd7a725d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get class list: 0, 1, ..., 9\n",
    "class_list = np.sort(np.unique(y_train))\n",
    "\n",
    "# Create model list\n",
    "mdl_logic_list = []\n",
    "for c in class_list:\n",
    "    mdl_logic_list.append(LogisticRegression(max_iter=1000))\n",
    "\n",
    "# Train models seperately\n",
    "for i in range(len(class_list)):\n",
    "    start_time = time.time()\n",
    "    mdl_logic_list[i].fit(x_train, (y_train == class_list[i]).astype(int))\n",
    "    end_time = time.time()\n",
    "    print(f'Training class {class_list[i]}, Training time: {end_time - start_time:.2f} seconds')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c5c9337-970e-4c15-a28e-ba0c3363de9f",
   "metadata": {},
   "source": [
    "## 9.构建基于支持向量机的一对一模型识别手写字母"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "a5a60dc1-d615-4d0a-b560-3959bc4035eb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training time: 0.20 seconds\n",
      "Accuracy: 0.9896\n"
     ]
    }
   ],
   "source": [
    "# Define logic regression classifier\n",
    "mdl_logic_ovo = OneVsOneClassifier(LogisticRegression(max_iter=1000))\n",
    "\n",
    "# Train model\n",
    "start_time = time.time()\n",
    "mdl_logic_ovo.fit(x_train, y_train)\n",
    "end_time = time.time()\n",
    "\n",
    "print(f'Training time: {end_time - start_time:.2f} seconds')\n",
    "\n",
    "# Make predictions and evaluate the model\n",
    "y_pred = mdl_logic_ovo.predict(x_test)\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f'Accuracy: {accuracy:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe172857-8af5-4775-9034-fff3b8acbdcb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get class list: 0, 1, ..., 9\n",
    "class_list = np.sort(np.unique(y_train))\n",
    "\n",
    "# Create model matrix to save models\n",
    "mdl_logic_matrix = {}\n",
    "for cls_p in class_list:\n",
    "    mdl_logic_matrix[cls_p] = {}\n",
    "    for cls_n in class_list:\n",
    "        if cls_p == cls_n:\n",
    "            continue\n",
    "        mdl_logic_matrix[cls_p][cls_n] = LogisticRegression(max_iter=1000)\n",
    "\n",
    "for cls_p in class_list:\n",
    "    # Training data of positive class\n",
    "    x_train_ovo_p = x_train[(y_train == cls_p), :]\n",
    "    y_train_ovo_p = np.ones(x_train_ovo_p.shape[0])\n",
    "\n",
    "    # Testing data of positive class\n",
    "    x_test_ovo_p = x_test[(y_test == cls_p), :]\n",
    "    y_test_ovo_p = np.ones(x_test_ovo_p.shape[0])\n",
    "\n",
    "    for cls_n in class_list:\n",
    "        if cls_p == cls_n:\n",
    "            continue\n",
    "\n",
    "        # Training data of negative class\n",
    "        x_train_ovo_n = x_train[(y_train == cls_n), :]\n",
    "        y_train_ovo_n = np.zeros(x_train_ovo_n.shape[0])\n",
    "\n",
    "        # Testing data of negative class\n",
    "        x_test_ovo_n = x_test[(y_test == cls_n), :]\n",
    "        y_test_ovo_n = np.zeros(x_test_ovo_n.shape[0])\n",
    "\n",
    "        # Concatenate data for training\n",
    "        x_train_ovo = np.concatenate((x_train_ovo_p, x_train_ovo_n), axis=0)\n",
    "        y_train_ovo = np.concatenate((y_train_ovo_p, y_train_ovo_n), axis=0)\n",
    "\n",
    "        # Model training\n",
    "        start_time = time.time()\n",
    "        mdl_logic_matrix[cls_p][cls_n].fit(x_train_ovo, y_train_ovo)\n",
    "        end_time = time.time()\n",
    "\n",
    "        # Concatenate data for testing\n",
    "        x_test_ovo = np.concatenate((x_test_ovo_p, x_test_ovo_n), axis=0)\n",
    "        y_test_ovo = np.concatenate((y_test_ovo_p, y_test_ovo_n), axis=0)\n",
    "\n",
    "        # Test model on sub-task\n",
    "        y_proba_ovo = mdl_logic_matrix[cls_p][cls_n].predict_proba(x_test_ovo) # Output ratio\n",
    "\n",
    "        # Display results\n",
    "        _, (tp, fp, tn, fn) = cls_counts(y_test_ovo, y_proba_ovo[:, 1])\n",
    "        precision, recall, specificity, accuracy, f1 = get_scores(tp, fp, tn, fn)\n",
    "        print(f'Training class {cls_p} ({x_train_ovo_p.shape[0]}) vs class {cls_n} ({x_train_ovo_n.shape[0]}), Training time: {end_time - start_time:.2f} seconds, Precision: {precision:.4f}, Recall (Sensitivity): {recall:.4f}, Specificity: {specificity:.4f}, Accuracy: {accuracy:.4f}, F1-Score: {f1:.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f5ced2e-2e62-4c8c-b599-66273118f69f",
   "metadata": {},
   "source": [
    "## 10.构建决策树识别手写字母"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "c70daf5d-133f-4cf8-8cf7-6f1615a09c3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training time: 5.73 seconds\n"
     ]
    }
   ],
   "source": [
    "# Define DecisionTree classifier\n",
    "mdl_dt = tree.DecisionTreeClassifier()\n",
    "\n",
    "# Train model\n",
    "start_time = time.time()\n",
    "mdl_dt.fit(x_train, y_train)\n",
    "end_time = time.time()\n",
    "\n",
    "print(f'Training time: {end_time - start_time:.2f} seconds')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae37e582-4659-49d6-9bd7-3aa659c42de7",
   "metadata": {},
   "source": [
    "## 11.构建不同子树数量的随机森林模型识别手写字母"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "96b6d424-c8d6-443a-98ba-9f8b1fd95e24",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training time: 25.94 seconds\n",
      "Precision: 0.9100, Recall: 0.9269, Accuracy: 0.9813, F1-Score: 0.9184\n",
      "Precision: 0.9898, Recall: 0.9383, Accuracy: 0.9919, F1-Score: 0.9634\n"
     ]
    }
   ],
   "source": [
    "# Define Random Forest classifier\n",
    "mdl_rf = RandomForestClassifier(n_estimators=100)\n",
    "\n",
    "# Train model\n",
    "start_time = time.time()\n",
    "mdl_rf.fit(x_train, y_train)\n",
    "end_time = time.time()\n",
    "\n",
    "print(f'Training time: {end_time - start_time:.2f} seconds')\n",
    "y_pred_dt = mdl_dt.predict(x_test)\n",
    "y_proba_dt = mdl_dt.predict_proba(x_test) # Output ratio\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred_dt)\n",
    "precision = precision_score(y_test, y_pred_dt)\n",
    "recall = recall_score(y_test, y_pred_dt)\n",
    "f1 = f1_score(y_test, y_pred_dt)\n",
    "\n",
    "print(f'Precision: {precision:.4f}, Recall: {recall:.4f}, Accuracy: {accuracy:.4f}, F1-Score: {f1:.4f}')\n",
    "\n",
    "y_pred_rf = mdl_rf.predict(x_test)\n",
    "y_proba_rf = mdl_rf.predict_proba(x_test) # Output ratio\n",
    "\n",
    "accuracy = accuracy_score(y_test, y_pred_rf)\n",
    "precision = precision_score(y_test, y_pred_rf)\n",
    "recall = recall_score(y_test, y_pred_rf)\n",
    "f1 = f1_score(y_test, y_pred_rf)\n",
    "\n",
    "print(f'Precision: {precision:.4f}, Recall: {recall:.4f}, Accuracy: {accuracy:.4f}, F1-Score: {f1:.4f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b451437-fdea-4bce-9974-597e6432c211",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
